package com.time.filter;

import com.onelogin.saml2.Auth;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

public class LoggingFilter implements Filter {
    private static final Logger log = LoggerFactory.getLogger(LoggingFilter.class);
    
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        log.info("LoggingFilter init...");
    }
    
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        
        Set<String> publicPaths = new HashSet<>(Arrays.asList("/home", "/login", "/login2", "/callback", "/callback-shuchen"));
        
        if (request instanceof HttpServletRequest) {
            HttpServletRequest httpRequest = (HttpServletRequest) request;
            
            // 获取工程路径
            String contextPath = httpRequest.getContextPath();
            
            String servletPath = httpRequest.getServletPath();
            
            // 获取请求资源路径
            String requestURI = httpRequest.getRequestURI();
            
            // 获取原始URL
            String requestURL = httpRequest.getRequestURL().toString();
            
            // 获取查询参数
            String queryString = httpRequest.getQueryString();
            
            // 获取完整的URL（包括参数）
            String fullURL = requestURL;
            if (!StringUtils.isEmpty(queryString)) {
                fullURL += "?" + queryString;
            }
            
            log.info("Requested contextPath: {}", contextPath);
            log.info("Requested servletPath: {}", servletPath);
            log.info("Requested URI: {}", requestURI);
            log.info("Requested URL: {}", requestURL);
            log.info("Query String: {}", queryString);
            log.info("Full URL: {}", fullURL);
            
            
            if (publicPaths.contains(servletPath)) {
                // 公共资源直接放行
                chain.doFilter(request, response);
            } else {
                //保护受限资源，需要登陆验证
                log.info("正在访问受保护资源...");
                HttpSession session = httpRequest.getSession();
                String currentUser = (String) session.getAttribute("currentUser");
                log.info("当前用户：[{}]", currentUser);
                if (StringUtils.isEmpty(currentUser)) {
                    //用户session为空，重新登陆
                    log.info("用户session为空，OKTA 重新登陆...");
                    oneLoginAuthSSO(servletPath, fullURL, (HttpServletRequest) request, (HttpServletResponse) response);
                    
                } else {
                    //已登陆，放行
                    chain.doFilter(request, response);
                }
            }
        }
    }
    
    
    private void redirectToOkta(HttpServletRequest request, HttpServletResponse response, String redirectUrl) throws IOException {
        response.sendRedirect(redirectUrl);
    }
    
    
    @Override
    public void destroy() {
        log.info("LoggingFilter destroy...");
    }
    
    
    /**
     * okta登陆
     *
     * @param servletPath
     * @param redirectUrl
     * @param request
     * @param response
     * @return com.onelogin.saml2.Auth
     * @author yonghao.tang
     * @date 2024/7/11 上午9:54
     */
    protected void oneLoginAuthSSO(String servletPath, String redirectUrl, HttpServletRequest request, HttpServletResponse response) {
        //构造Auth客户端，默认使用classpath下的onelogin.saml.properties，也可指定文件
        Auth auth = null;
        try {
            if ("/resource2".equals(servletPath)) {
                auth = new Auth("shuchen.saml.properties", request, response);
            } else {
                //使用默认的配置构建
                auth = new Auth(request, response);
            }
            //RelayState 回调URL
            auth.login(redirectUrl);
        } catch (Exception e) {
            log.error("OneLogin init error", e);
        }
    }
}
